﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferenceRoleMaster")]
	public class ConferenceRoleMasterController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferenceRoleMaster;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferenceRoleMasterModel();
			model.ConferenceId = conferenceId;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferenceRoleMasterModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = DbContext.ConferenceRoleMaster.AsNoTracking()
					.Where(x => !string.IsNullOrEmpty(x.Status) &&
						x.ConferenceId == model.ConferenceId);

			if (!string.IsNullOrWhiteSpace(model.SelRoleName))
			{
				sql = sql.Where(x => x.RoleName.Contains(model.SelRoleName));
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.UpdateDate).ThenBy(x => x.RoleName).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				RoleName = x.RoleName,
				Status = x.Status,
				Sort = x.Sort,
				Remark = x.Remark,
				Creator = x.Creator,
				CreateIP = x.CreateIP,
				CreateDate = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
							x.CreateDate.Value.ToString("yyyy-MM-dd") :
							x.CreateDate.Value.ToString("MM/dd/yyyy")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetEditData(string id)
		{
			var result = await DbContext.ConferenceRoleMaster.AsNoTracking().FirstOrDefaultAsync(x => x.ID == id);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateSuccessJsonResult(string.Empty, result),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Create/{ConferenceId}")]
		public async Task<JsonResult> Create(ConferenceRoleMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceRoleMaster
					.FirstOrDefaultAsync(x => x.ConferenceId == model.ConferenceId &&
						x.RoleName == model.RoleName);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.RoleName)),
						JsonRequestBehavior.AllowGet);
			}

			var conferenceRoleMaster = new ConferenceRoleMaster
			{
				ID = Utility.GetTableId(ConstValues.TableName.ConferenceRoleMaster),
				RoleName = model.RoleName?.Trim(),
				ConferenceId = model.ConferenceId,
				Status = model.Status,
				Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort,
				Remark = model.Remark?.Trim(),
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.ConferenceRoleMaster.Add(conferenceRoleMaster);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Modify/{ConferenceId}")]
		public async Task<JsonResult> Modify(ConferenceRoleMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var exist = await DbContext.ConferenceRoleMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.ID != model.Id &&
						x.ConferenceId == model.ConferenceId &&
						x.RoleName == model.RoleName);

			if (exist != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.RoleName)),
						JsonRequestBehavior.AllowGet);
			}

			var result = await DbContext.ConferenceRoleMaster
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				if (result.RoleName == ConstValues.CA && model.RoleName != ConstValues.CA)
				{
					return JsonCamelCase(Utility.CreateFailJsonResult(Resources.CfmCanNotEditAdmin),
							JsonRequestBehavior.AllowGet);
				}

				result.RoleName = model.RoleName?.Trim();
				result.Status = model.Status;
				result.Sort = model.Sort.HasValue ? model.Sort.Value : ConstValues.DefaultSort;
				result.Remark = model.Remark?.Trim();
				result.Updater = LoginUser.UserName;
				result.UpdateIP = LoginUser.IP;
				result.UpdateDate = DateTime.Now;

				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("Delete/{ConferenceId}")]
		public async Task<JsonResult> Delete(ConferenceRoleMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceRoleMaster.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				if (result.RoleName == ConstValues.CA)
				{
					return JsonCamelCase(Utility.CreateFailJsonResult(Resources.CfmCanNotDeleteAdmin),
							JsonRequestBehavior.AllowGet);
				}

				using (var transaction = DbContext.Database.BeginTransaction())
				{
					DbContext.ConferenceRoleMaster.Remove(result);

					var conferenceUserAndRoleRelationList = await DbContext.ConferenceUserAndRoleRelation
							.Where(x => x.RoleId == model.Id).ToListAsync();
					DbContext.ConferenceUserAndRoleRelation.RemoveRange(conferenceUserAndRoleRelationList);

					var conferenceGroupAndRoleRelationList = await DbContext.ConferenceGroupAndRoleRelation
							.Where(x => x.RoleId == model.Id).ToListAsync();
					DbContext.ConferenceGroupAndRoleRelation.RemoveRange(conferenceGroupAndRoleRelationList);

					var conferenceRoleAndActionRelationList = await DbContext.ConferenceRoleAndActionRelation
							.Where(x => x.RoleId == model.Id).ToListAsync();
					DbContext.ConferenceRoleAndActionRelation.RemoveRange(conferenceRoleAndActionRelationList);

					await DbContext.SaveChangesAsync();
					transaction.Commit();
				}

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}

		public async Task<JsonCamelCaseResult> GetActionData(string roleId, ConferenceRoleMasterModel model)
		{
			var sql = DbContext.ConferenceRoleAndActionRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 &&
						x.RoleId == roleId &&
						x.ConferenceId == model.ConferenceId);

			var sqlResult = await sql.ToListAsync();
			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				RoleName = DbContext.ConferenceRoleMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.RoleId)?.RoleName,
				ActionName = DbContext.ConferenceActionMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.ActionId)?.ActionName,
			})
			.OrderBy(x => x.ActionName).ToList();

			return JsonCamelCase(new
			{
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonResult> GetAction(ConferenceRoleMasterModel model)
		{
			var result = await DbContext.ConferenceActionMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 &&
						x.ConferenceId == model.ConferenceId)
					.OrderBy(x => x.Sort)
					.ThenBy(x => x.ActionName)
					.Select(x => new
					{
						Id = x.ID,
						ActionName = x.ActionName
					})
					.ToListAsync();

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		[Route("CreateAction/{ConferenceId}")]
		public async Task<JsonResult> CreateAction(ConferenceRoleMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			for (int index = 0; index < model.ActionId.Length; index++)
			{
				string temp = model.ActionId[index];
				var result = await DbContext.ConferenceRoleAndActionRelation
						.FirstOrDefaultAsync(x => x.RoleId == model.RoleId &&
							x.ActionId == temp &&
							x.ConferenceId == model.ActConferenceId);

				if (result == null)
				{
					var conferenceRoleAndActionRelation = new ConferenceRoleAndActionRelation
					{
						ID = Utility.GetTableId(ConstValues.TableName.ConferenceRoleAndActionRelation),
						ConferenceId = model.ActConferenceId,
						RoleId = model.RoleId,
						ActionId = temp,
						Status = ConstValues.Status.正常,
						Sort = ConstValues.DefaultSort,
						Remark = string.Empty,
						Creator = LoginUser.UserName,
						CreateIP = LoginUser.IP,
						CreateDate = DateTime.Now
					};

					DbContext.ConferenceRoleAndActionRelation.Add(conferenceRoleAndActionRelation);
				}
			}
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("DeleteAction/{ConferenceId}")]
		public async Task<JsonResult> DeleteAction(ConferenceRoleMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceRoleAndActionRelation.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result != null)
			{
				DbContext.ConferenceRoleAndActionRelation.Remove(result);
				await DbContext.SaveChangesAsync();

				return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
						JsonRequestBehavior.AllowGet);
			}
			else
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}
		}
	}
}